﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NetCommon
{
    /// <summary>
    /// 消息长度编码和解码
    /// </summary>
    public class LengthEncoding
    {
        /// <summary>
        /// 消息长度编码
        /// </summary>
        /// <param name="buff">协议消息（模块号 + 命令号 + 数据）</param>
        /// <returns></returns>
        public static byte[] Encode(byte[] buff)
        {
            ByteArray ba = new ByteArray();
            //长度用 int 表示， int 占用4个字节
            //把消息长度写入流里面
            ba.Write(buff.Length);
            ba.Write(buff);
            //取出消息的长度（从 byte[] 中取出）
            buff = ba.GetBuff();
            ba.Close();
            return buff;
        }
        /// <summary>
        /// 消息长度解码
        /// </summary>
        /// <param name="buff"></param>
        /// <returns></returns>
        public static byte[] Decode(ref List<byte> buff)
        {
            //buff 是从 接收到的数据缓存里面拿出来的数据
            //消息缓存不足4字节，消息头不足
            if (buff.Count<4)
            {
                return null;
            }
            //数据存到内存流里面
            ByteArray ba = new ByteArray(buff.ToArray());
            //读取消息头(消息头代表消息长度)
            int len;
            ba.Read(out len);
            //缓存的消息长度不是一个完整是消息
            //buff.Count - 4 除去消息头大小
            if (len>buff.Count - 4)
            {
                return null;
            }

            //以下得到的是 至少一个完整消息的情况
            //读取当前消息体（除去消息头的真实消息）
            byte[] ret;
            ba.Read(out ret, len);
            //读取缓存中剩余的消息
            byte[] temp;
            ba.Read(out temp, buff.Count - 4 - len);

            //清空缓存,放回剩余的数据
            buff.Clear();
            buff.AddRange(temp);
            ba.Close();
            return ret;
        }
    }
}
